// utility standard header
#pragma once
#ifndef _UTILITY_
#define _UTILITY_
#ifndef RC_INVOKED
#include <xstddef>
#include <iosfwd>
#include <type_traits>

 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,_STL_WARNING_LEVEL)
 #pragma warning(disable: _STL_DISABLED_WARNINGS)
 #pragma push_macro("new")
 #undef new

_STD_BEGIN
		// TEMPLATE FUNCTION _Min_value
template<class _Ty>
	_Post_equal_to_(_Right < _Left ? _Right : _Left)
	constexpr const _Ty& _Min_value(const _Ty& _Left, const _Ty& _Right)
		_NOEXCEPT_OP(_NOEXCEPT_OP(_Right < _Left))
	{	// return smaller of _Left and _Right
	return (_Right < _Left ? _Right : _Left);
	}

		// TEMPLATE FUNCTION _Max_value
template<class _Ty>
	_Post_equal_to_(_Left < _Right ? _Right : _Left)
	constexpr const _Ty& _Max_value(const _Ty& _Left, const _Ty& _Right)
		_NOEXCEPT_OP(_NOEXCEPT_OP(_Left < _Right))
	{	// return larger of _Left and _Right
	return (_Left < _Right ? _Right : _Left);
	}

		// TEMPLATE FUNCTION iter_swap (from <algorithm>)
template<class _FwdIt1,
	class _FwdIt2> inline
	void iter_swap(_FwdIt1 _Left, _FwdIt2 _Right)
	{	// swap *_Left and *_Right
	swap(*_Left, *_Right);
	}

		// TEMPLATE FUNCTION swap
template<class _Ty,
	size_t _Size,
	class> inline
	void swap(_Ty (&_Left)[_Size], _Ty (&_Right)[_Size])
		_NOEXCEPT_OP(_Is_nothrow_swappable<_Ty>::value)
	{	// exchange arrays stored at _Left and _Right
	if (&_Left != &_Right)
		{	// worth swapping, swap ranges
		_Ty *_First1 = _Left;
		_Ty *_Last1 = _First1 + _Size;
		_Ty *_First2 = _Right;
		for (; _First1 != _Last1; ++_First1, ++_First2)
			_STD iter_swap(_First1, _First2);
		}
	}

template<class _Ty,
	class> inline
	void swap(_Ty& _Left, _Ty& _Right)
		_NOEXCEPT_OP(is_nothrow_move_constructible<_Ty>::value
			&& is_nothrow_move_assignable<_Ty>::value)
	{	// exchange values stored at _Left and _Right
	_Ty _Tmp = _STD move(_Left);
	_Left = _STD move(_Right);
	_Right = _STD move(_Tmp);
	}

		// TEMPLATE FUNCTION _Swap_adl
template<class _Ty> inline
	void _Swap_adl(_Ty& _Left, _Ty& _Right)
		_NOEXCEPT_OP(_Is_nothrow_swappable<_Ty>::value)
	{	// exchange values stored at _Left and _Right, using ADL
	swap(_Left, _Right);
	}

		// STRUCT piecewise_construct_t
struct piecewise_construct_t
	{	// tag type for pair tuple arguments
	};

constexpr piecewise_construct_t piecewise_construct{};

		// TEMPLATE STRUCT pair
template<class...>
	class tuple;

template<class _Ty1,
	class _Ty2>
	struct pair
	{	// store a pair of values
	typedef pair<_Ty1, _Ty2> _Myt;
	typedef _Ty1 first_type;
	typedef _Ty2 second_type;

	template<class _Uty1 = _Ty1,
		class _Uty2 = _Ty2,
		class = enable_if_t<is_default_constructible<_Uty1>::value
						&& is_default_constructible<_Uty2>::value> >
		constexpr pair()
		: first(), second()
		{	// default construct
		}

	template<class _Uty1 = _Ty1,
		class _Uty2 = _Ty2,
		class = enable_if_t<is_copy_constructible<_Uty1>::value
						&& is_copy_constructible<_Uty2>::value>,
		enable_if_t<is_convertible<const _Uty1&, _Uty1>::value
				&& is_convertible<const _Uty2&, _Uty2>::value, int> = 0>
		constexpr pair(const _Ty1& _Val1, const _Ty2& _Val2)
		: first(_Val1), second(_Val2)
		{	// construct from specified values
		}

	template<class _Uty1 = _Ty1,
		class _Uty2 = _Ty2,
		class = enable_if_t<is_copy_constructible<_Uty1>::value
						&& is_copy_constructible<_Uty2>::value>,
		enable_if_t<!is_convertible<const _Uty1&, _Uty1>::value
				|| !is_convertible<const _Uty2&, _Uty2>::value, int> = 0>
		constexpr explicit pair(const _Ty1& _Val1, const _Ty2& _Val2)
		: first(_Val1), second(_Val2)
		{	// construct from specified values
		}

	pair(const pair&) = default;
	pair(pair&&) = default;

	template<class _Other1,
		class _Other2,
		class = enable_if_t<is_constructible<_Ty1, const _Other1&>::value
						&& is_constructible<_Ty2, const _Other2&>::value>,
		enable_if_t<is_convertible<const _Other1&, _Ty1>::value
				&& is_convertible<const _Other2&, _Ty2>::value, int> = 0>
		constexpr pair(const pair<_Other1, _Other2>& _Right)
		: first(_Right.first), second(_Right.second)
		{	// construct from compatible pair
		}

	template<class _Other1,
		class _Other2,
		class = enable_if_t<is_constructible<_Ty1, const _Other1&>::value
						&& is_constructible<_Ty2, const _Other2&>::value>,
		enable_if_t<!is_convertible<const _Other1&, _Ty1>::value
				|| !is_convertible<const _Other2&, _Ty2>::value, int> = 0>
		constexpr explicit pair(const pair<_Other1, _Other2>& _Right)
		: first(_Right.first), second(_Right.second)
		{	// construct from compatible pair
		}

	template<class _Other1,
		class _Other2>
		_Myt& operator=(const pair<_Other1, _Other2>& _Right)
		{	// assign from compatible pair
		first = _Right.first;
		second = _Right.second;
		return (*this);
		}

	template<class _Tuple1,
		class _Tuple2,
		size_t... _Indexes1,
		size_t... _Indexes2> inline
		pair(_Tuple1& _Val1,
			_Tuple2& _Val2,
			index_sequence<_Indexes1...>,
			index_sequence<_Indexes2...>);

	template<class... _Types1,
		class... _Types2> inline
		pair(piecewise_construct_t,
			tuple<_Types1...> _Val1,
			tuple<_Types2...> _Val2);

	template<class _Other1,
		class _Other2,
		class = enable_if_t<is_constructible<_Ty1, _Other1>::value
						&& is_constructible<_Ty2, _Other2>::value>,
		enable_if_t<is_convertible<_Other1, _Ty1>::value
				&& is_convertible<_Other2, _Ty2>::value, int> = 0>
		constexpr pair(_Other1&& _Val1, _Other2&& _Val2)
			_NOEXCEPT_OP((is_nothrow_constructible<_Ty1, _Other1>::value
				&& is_nothrow_constructible<_Ty2, _Other2>::value))
		: first(_STD forward<_Other1>(_Val1)),
				second(_STD forward<_Other2>(_Val2))
		{	// construct from moved values
		}

	template<class _Other1,
		class _Other2,
		class = enable_if_t<is_constructible<_Ty1, _Other1>::value
						&& is_constructible<_Ty2, _Other2>::value>,
		enable_if_t<!is_convertible<_Other1, _Ty1>::value
				|| !is_convertible<_Other2, _Ty2>::value, int> = 0>
		constexpr explicit pair(_Other1&& _Val1, _Other2&& _Val2)
			_NOEXCEPT_OP((is_nothrow_constructible<_Ty1, _Other1>::value
				&& is_nothrow_constructible<_Ty2, _Other2>::value))
		: first(_STD forward<_Other1>(_Val1)),
				second(_STD forward<_Other2>(_Val2))
		{	// construct from moved values
		}

	template<class _Other1,
		class _Other2,
		class = enable_if_t<is_constructible<_Ty1, _Other1>::value
						&& is_constructible<_Ty2, _Other2>::value>,
		enable_if_t<is_convertible<_Other1, _Ty1>::value
				&& is_convertible<_Other2, _Ty2>::value, int> = 0>
		constexpr pair(pair<_Other1, _Other2>&& _Right)
			_NOEXCEPT_OP((is_nothrow_constructible<_Ty1, _Other1>::value
				&& is_nothrow_constructible<_Ty2, _Other2>::value))
		: first(_STD forward<_Other1>(_Right.first)),
			second(_STD forward<_Other2>(_Right.second))
		{	// construct from moved compatible pair
		}

	template<class _Other1,
		class _Other2,
		class = enable_if_t<is_constructible<_Ty1, _Other1>::value
						&& is_constructible<_Ty2, _Other2>::value>,
		enable_if_t<!is_convertible<_Other1, _Ty1>::value
				|| !is_convertible<_Other2, _Ty2>::value, int> = 0>
		constexpr explicit pair(pair<_Other1, _Other2>&& _Right)
			_NOEXCEPT_OP((is_nothrow_constructible<_Ty1, _Other1>::value
				&& is_nothrow_constructible<_Ty2, _Other2>::value))
		: first(_STD forward<_Other1>(_Right.first)),
			second(_STD forward<_Other2>(_Right.second))
		{	// construct from moved compatible pair
		}

	template<class _Other1,
		class _Other2>
		_Myt& operator=(pair<_Other1, _Other2>&& _Right)
		{	// assign from moved compatible pair
		first = _STD forward<_Other1>(_Right.first);
		second = _STD forward<_Other2>(_Right.second);
		return (*this);
		}

	_Myt& operator=(_Myt&& _Right)
		_NOEXCEPT_OP((is_nothrow_move_assignable<_Ty1>::value
			&& is_nothrow_move_assignable<_Ty2>::value))
		{	// assign from moved pair
		first = _STD forward<_Ty1>(_Right.first);
		second = _STD forward<_Ty2>(_Right.second);
		return (*this);
		}

	_Myt& operator=(const _Myt& _Right)
		{	// assign from copied pair
		first = _Right.first;
		second = _Right.second;
		return (*this);
		}

	void swap(_Myt& _Right)
		_NOEXCEPT_OP(_Is_nothrow_swappable<_Ty1>::value
			&& _Is_nothrow_swappable<_Ty2>::value)
		{	// exchange contents with _Right
		if (this != _STD addressof(_Right))
			{	// different, worth swapping
			_Swap_adl(first, _Right.first);
			_Swap_adl(second, _Right.second);
			}
		}

	_Ty1 first;		// the first stored value
	_Ty2 second;	// the second stored value
	};

		// pair TEMPLATE FUNCTIONS

template<class _Ty1,
	class _Ty2,
	class = enable_if_t<_Is_swappable<_Ty1>::value && _Is_swappable<_Ty2>::value>> inline
	void swap(pair<_Ty1, _Ty2>& _Left, pair<_Ty1, _Ty2>& _Right)
		_NOEXCEPT_OP(_NOEXCEPT_OP(_Left.swap(_Right)))
	{	// swap _Left and _Right pairs
	_Left.swap(_Right);
	}

template<class _Ty1,
	class _Ty2> inline
	constexpr bool operator==(const pair<_Ty1, _Ty2>& _Left,
		const pair<_Ty1, _Ty2>& _Right)
	{	// test for pair equality
	return (_Left.first == _Right.first && _Left.second == _Right.second);
	}

template<class _Ty1,
	class _Ty2> inline
	constexpr bool operator!=(const pair<_Ty1, _Ty2>& _Left,
		const pair<_Ty1, _Ty2>& _Right)
	{	// test for pair inequality
	return (!(_Left == _Right));
	}

template<class _Ty1,
	class _Ty2> inline
	constexpr bool operator<(const pair<_Ty1, _Ty2>& _Left,
		const pair<_Ty1, _Ty2>& _Right)
	{	// test if _Left < _Right for pairs
	return (_Left.first < _Right.first ||
		(!(_Right.first < _Left.first) && _Left.second < _Right.second));
	}

template<class _Ty1,
	class _Ty2> inline
	constexpr bool operator>(const pair<_Ty1, _Ty2>& _Left,
		const pair<_Ty1, _Ty2>& _Right)
	{	// test if _Left > _Right for pairs
	return (_Right < _Left);
	}

template<class _Ty1,
	class _Ty2> inline
	constexpr bool operator<=(const pair<_Ty1, _Ty2>& _Left,
		const pair<_Ty1, _Ty2>& _Right)
	{	// test if _Left <= _Right for pairs
	return (!(_Right < _Left));
	}

template<class _Ty1,
	class _Ty2> inline
	constexpr bool operator>=(const pair<_Ty1, _Ty2>& _Left,
		const pair<_Ty1, _Ty2>& _Right)
	{	// test if _Left >= _Right for pairs
	return (!(_Left < _Right));
	}

	// TEMPLATE FUNCTION make_pair

template<class _Ty1,
	class _Ty2> inline
	constexpr pair<typename _Unrefwrap<_Ty1>::type,
		typename _Unrefwrap<_Ty2>::type>
		make_pair(_Ty1&& _Val1, _Ty2&& _Val2)
	{	// return pair composed from arguments
	typedef pair<typename _Unrefwrap<_Ty1>::type,
		typename _Unrefwrap<_Ty2>::type> _Mypair;
	return (_Mypair(_STD forward<_Ty1>(_Val1),
		_STD forward<_Ty2>(_Val2)));
	}

		// TEMPLATE OPERATORS
	namespace rel_ops
		{	// nested namespace to hide relational operators from std
template<class _Ty> inline
	bool operator!=(const _Ty& _Left, const _Ty& _Right)
	{	// test for inequality, in terms of equality
	return (!(_Left == _Right));
	}

template<class _Ty> inline
	bool operator>(const _Ty& _Left, const _Ty& _Right)
	{	// test if _Left > _Right, in terms of operator<
	return (_Right < _Left);
	}

template<class _Ty> inline
	bool operator<=(const _Ty& _Left, const _Ty& _Right)
	{	// test if _Left <= _Right, in terms of operator<
	return (!(_Right < _Left));
	}

template<class _Ty> inline
	bool operator>=(const _Ty& _Left, const _Ty& _Right)
	{	// test if _Left >= _Right, in terms of operator<
	return (!(_Left < _Right));
	}
		}
_STD_END

_STD_BEGIN
template<class _Ty,
	size_t _Size>
	class array;

	// TEMPLATE STRUCT tuple_size
template<class _Tuple>
	struct tuple_size;

template<class _Ty,
	size_t _Size>
	struct tuple_size<array<_Ty, _Size> >
		: integral_constant<size_t, _Size>
	{	// struct to determine number of elements in array
	};

template<class _Ty1,
	class _Ty2>
	struct tuple_size<pair<_Ty1, _Ty2> >
	: integral_constant<size_t, 2>
	{	// size of pair
	};

template<class... _Types>
	struct tuple_size<tuple<_Types...> >
	: integral_constant<size_t, sizeof...(_Types)>
	{	// size of tuple
	};


template<class _Tuple>
	struct tuple_size<const _Tuple>
	: tuple_size<_Tuple>
	{	// size of const tuple
	};

template<class _Tuple>
	struct tuple_size<volatile _Tuple>
	: tuple_size<_Tuple>
	{	// size of volatile tuple
	};

template<class _Tuple>
	struct tuple_size<const volatile _Tuple>
	: tuple_size<_Tuple>
	{	// size of const volatile tuple
	};

template<class _Ty>
	constexpr size_t tuple_size_v = tuple_size<_Ty>::value;

	// CLASS tuple_element (find element by index)
template<size_t _Index,
	class _Tuple>
	struct tuple_element;

template<size_t _Idx,
	class _Ty,
	size_t _Size>
	struct tuple_element<_Idx, array<_Ty, _Size> >
	{	// struct to determine type of element _Idx in array
	static_assert(_Idx < _Size, "array index out of bounds");

	typedef _Ty type;
	};

template<class _Ty1,
	class _Ty2>
	struct tuple_element<0, pair<_Ty1, _Ty2> >
	{	// struct to determine type of element 0 in pair
	typedef _Ty1 type;
	};

template<class _Ty1,
	class _Ty2>
	struct tuple_element<1, pair<_Ty1, _Ty2> >
	{	// struct to determine type of element 1 in pair
	typedef _Ty2 type;
	};

template<size_t _Index>
	struct tuple_element<_Index, tuple<> >
	{	// enforce bounds checking
	static_assert(_Always_false<integral_constant<size_t, _Index> >::value,
		"tuple index out of bounds");
	};

template<class _This,
	class... _Rest>
	struct tuple_element<0, tuple<_This, _Rest...> >
	{	// select first element
	typedef _This type;
	typedef tuple<_This, _Rest...> _Ttype;
	};

template<size_t _Index,
	class _This,
	class... _Rest>
	struct tuple_element<_Index, tuple<_This, _Rest...> >
		: public tuple_element<_Index - 1, tuple<_Rest...> >
	{	// recursive tuple_element definition
	};


template<size_t _Index,
	class _Tuple>
	struct tuple_element<_Index, const _Tuple>
		: public tuple_element<_Index, _Tuple>
	{	// tuple_element for const
	typedef tuple_element<_Index, _Tuple> _Mybase;
	typedef typename add_const<typename _Mybase::type>::type type;
	};

template<size_t _Index,
	class _Tuple>
	struct tuple_element<_Index, volatile _Tuple>
		: public tuple_element<_Index, _Tuple>
	{	// tuple_element for volatile
	typedef tuple_element<_Index, _Tuple> _Mybase;
	typedef typename add_volatile<typename _Mybase::type>::type type;
	};

template<size_t _Index,
	class _Tuple>
	struct tuple_element<_Index, const volatile _Tuple>
		: public tuple_element<_Index, _Tuple>
	{	// tuple_element for const volatile
	typedef tuple_element<_Index, _Tuple> _Mybase;
	typedef typename add_cv<typename _Mybase::type>::type type;
	};

template<size_t _Index,
	class _Tuple>
	using tuple_element_t = typename tuple_element<_Index, _Tuple>::type;

	// TUPLE INTERFACE TO pair
template<class _Ret,
	class _Pair> inline
	constexpr _Ret _Pair_get(_Pair& _Pr,
		integral_constant<size_t, 0>) _NOEXCEPT
	{	// get reference to element 0 in pair _Pr
	return (_Pr.first);
	}

template<class _Ret,
	class _Pair> inline
	constexpr _Ret _Pair_get(_Pair& _Pr,
		integral_constant<size_t, 1>) _NOEXCEPT
	{	// get reference to element 1 in pair _Pr
	return (_Pr.second);
	}

template<size_t _Idx,
	class _Ty1,
	class _Ty2> inline
	constexpr typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type&
		get(pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT
	{	// get reference to element at _Idx in pair _Pr
	typedef typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type& _Rtype;
	return (_Pair_get<_Rtype>(_Pr, integral_constant<size_t, _Idx>()));
	}

template<class _Ty1,
	class _Ty2> inline
	constexpr _Ty1& get(pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT
	{	// get reference to element _Ty1 in pair _Pr
	return (_STD get<0>(_Pr));
	}

template<class _Ty2,
	class _Ty1> inline
	constexpr _Ty2& get(pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT
	{	// get reference to element _Ty2 in pair _Pr
	return (_STD get<1>(_Pr));
	}

template<size_t _Idx,
	class _Ty1,
	class _Ty2> inline
	constexpr const typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type&
		get(const pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT
	{	// get const reference to element at _Idx in pair _Pr
	typedef const typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type&
		_Ctype;
	return (_Pair_get<_Ctype>(_Pr, integral_constant<size_t, _Idx>()));
	}

template<class _Ty1,
	class _Ty2> inline
	constexpr const _Ty1& get(const pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT
	{	// get const reference to element _Ty1 in pair _Pr
	return (_STD get<0>(_Pr));
	}

template<class _Ty2,
	class _Ty1> inline
	constexpr const _Ty2& get(const pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT
	{	// get const reference to element _Ty2 in pair _Pr
	return (_STD get<1>(_Pr));
	}

template<size_t _Idx,
	class _Ty1,
	class _Ty2> inline
	constexpr typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type&&
		get(pair<_Ty1, _Ty2>&& _Pr) _NOEXCEPT
	{	// get rvalue reference to element at _Idx in pair _Pr
	typedef typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type&& _RRtype;
	return (_STD forward<_RRtype>(_STD get<_Idx>(_Pr)));
	}

template<class _Ty1,
	class _Ty2> inline
	constexpr _Ty1&& get(pair<_Ty1, _Ty2>&& _Pr) _NOEXCEPT
	{	// get rvalue reference to element _Ty1 in pair _Pr
	return (_STD get<0>(_STD move(_Pr)));
	}

template<class _Ty2,
	class _Ty1> inline
	constexpr _Ty2&& get(pair<_Ty1, _Ty2>&& _Pr) _NOEXCEPT
	{	// get rvalue reference to element _Ty2 in pair _Pr
	return (_STD get<1>(_STD move(_Pr)));
	}

template<size_t _Idx,
	class _Ty1,
	class _Ty2> inline
	constexpr const typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type&&
		get(const pair<_Ty1, _Ty2>&& _Pr) _NOEXCEPT
	{	// get const rvalue reference to element at _Idx in pair _Pr
	typedef const typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type&& _RRtype;
	return (_STD forward<_RRtype>(_STD get<_Idx>(_Pr)));
	}

template<class _Ty1,
	class _Ty2> inline
	constexpr const _Ty1&& get(const pair<_Ty1, _Ty2>&& _Pr) _NOEXCEPT
	{	// get const rvalue reference to element _Ty1 in pair _Pr
	return (_STD get<0>(_STD move(_Pr)));
	}

template<class _Ty2,
	class _Ty1> inline
	constexpr const _Ty2&& get(const pair<_Ty1, _Ty2>&& _Pr) _NOEXCEPT
	{	// get const rvalue reference to element _Ty2 in pair _Pr
	return (_STD get<1>(_STD move(_Pr)));
	}

	// TEMPLATE FUNCTION exchange
template<class _Ty,
	class _Other = _Ty> inline
	_Ty exchange(_Ty& _Val, _Other&& _New_val)
	{	// assign _New_val to _Val, return previous _Val
	_Ty _Old_val = _STD move(_Val);
	_Val = _STD forward<_Other>(_New_val);
	return (_Old_val);
	}

	// TEMPLATE FUNCTION as_const
template<class _Ty> inline
	constexpr add_const_t<_Ty>& as_const(_Ty& _Val) _NOEXCEPT
	{	// view _Val through const lenses
	return (_Val);
	}

template<class _Ty>
	void as_const(const _Ty&&) = delete;

#if _HAS_CXX17
	// in_place TAG TYPE TEMPLATES
struct in_place_t
	{	// tag used to select a constructor which initializes a contained object in place
	explicit in_place_t() = default;
	};
/* inline */ constexpr in_place_t in_place{};

template<class>
	struct in_place_type_t
	{	// tag that selects a type to construct in place
	explicit in_place_type_t() = default;
	};
template<class _Ty>
	/* inline */ constexpr in_place_type_t<_Ty> in_place_type{};

template<size_t>
	struct in_place_index_t
	{	// tag that selects the index of a type to construct in place
	explicit in_place_index_t() = default;
	};
template<size_t _Idx>
	/* inline */ constexpr in_place_index_t<_Idx> in_place_index{};
#endif /* _HAS_CXX17 */
_STD_END

#if _HAS_TR1_NAMESPACE
_STD_BEGIN
namespace tr1 {	// TR1 additions
using _STD get;
using _STD tuple_element;
using _STD tuple_size;
}	// namespace tr1
_STD_END
#endif /* _HAS_TR1_NAMESPACE */

 #pragma pop_macro("new")
 #pragma warning(pop)
 #pragma pack(pop)
#endif /* RC_INVOKED */
#endif /* _UTILITY_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V6.50:0009 */
